package com.ruoyi.common.utils.http;


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson2.JSONObject;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class WebUtils {

    //get请求
    //url  请求地址
    //参数可放在 url或 outMap
    public static String httpGet(String url,Map<String,String> outMap) {

        HttpClient httpClient = HttpClients.createDefault();


        //get请求参数处理
        if(outMap!=null){
            url=url+getRequestStr(outMap);
        }

        HttpGet httpGet=new HttpGet(url);

        String result=null;
        try {
            HttpResponse response = httpClient.execute(httpGet);

            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity);

        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return result;
    }


    //post请求
    //url  请求地址
    //参数可放在 url或 outMap
    //isJson 是否以json格式传参
    public static String httpPost(String url,Map<String,String> outMap,boolean isJson) {

        HttpClient httpClient = HttpClients.createDefault();


        HttpPost httpPost=new HttpPost(url);

        String result=null;
        try {
            //get请求参数处理
            if(outMap!=null){
                if(isJson){
                    httpPost.setHeader("Accept", "application/json");
                    httpPost.setHeader("Content-Type", "application/json");

                    JSONObject json = postRequestJson(outMap);
                    httpPost.setEntity(new StringEntity(json.toString(),"UTF-8"));
                }else{
                    List<NameValuePair> list = postRequestList(outMap);
                    httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8"));
                }
            }
            HttpResponse response = httpClient.execute(httpPost);

            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity);


        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return result;
    }



    //get请求完整请求参数
    public static String getRequestStr(Map<String,String> map) {
        return "?"+ getParamStr(map);
    }

    //Map转String  key=value&key1=value1&...
    public static String getParamStr(Map<String,String> map) {

        //->  lambda表达式,相当于匿名函数,简洁速度慢
		/*map.forEach((key,value) ->{
			System.out.println(key+":"+value);
		});*/

        //简单,速度最慢
		/*Set<String> keySet = map.keySet();
		for (String key : keySet) {
			System.out.println(key+":"+map.get(key));
		}*/

        //迭代 删除时可用
		/*Set<Entry<String,String>> entrySet = map.entrySet();
		Iterator<Entry<String, String>> iterator = entrySet.iterator();
		while(iterator.hasNext()){
			Entry<String, String> entry = iterator.next();
			System.out.println(entry.getKey()+":"+entry.getValue());
		}*/


        StringBuilder sb=new StringBuilder();

        //速度最快  推荐
        Set<Entry<String,String>> entrySet = map.entrySet();
        for (Entry<String, String> entry : entrySet) {
            sb.append(entry.getKey());
            sb.append("=");
            sb.append(entry.getValue());
            sb.append("&");
        }

        return sb.toString();
    }

    //post请求完整请求参数
    public static List<NameValuePair> postRequestList(Map<String,String> map) {
        List<NameValuePair> list =new ArrayList<NameValuePair>();

        Set<Entry<String,String>> entrySet = map.entrySet();
        for (Entry<String, String> entry : entrySet) {
            list.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
        }

        return list;
    }
    //post请求完整请求参数(json)
    public static JSONObject postRequestJson(Map<String,String> map) {
        JSONObject json=new JSONObject();

        Set<Entry<String,String>> entrySet = map.entrySet();
        for (Entry<String, String> entry : entrySet) {
            json.put(entry.getKey(), entry.getValue());
        }

        return json;
    }




    public static String httpFile(String url, Map<String, String> param, File file) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 处理https链接
        if (url.startsWith("https://")) {
            httpClient = sslClient();
        }
        String resultString = "";
        CloseableHttpResponse response = null;
        HttpPost httppost = new HttpPost(url);
        try {
            // HttpMultipartMode.RFC6532参数的设定是为避免文件名为中文时乱码
            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
            // 设置请求的编码格式
            builder.setCharset(Consts.UTF_8);
            builder.setContentType(ContentType.MULTIPART_FORM_DATA);
            // 添加文件,也可以添加字节流
//			builder.addBinaryBody("file", file);
            //或者使用字节流也行,根据具体需要使用
            builder.addBinaryBody("file", Files.readAllBytes(file.toPath()),ContentType.APPLICATION_OCTET_STREAM,file.getName());
            // 或者builder.addPart("file",new FileBody(file));
            // 添加参数
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addTextBody(key, param.get(key));
                }
            }
            //httppost.addHeader("token", param.get("token"));
            HttpEntity reqEntity = builder.build();
            httppost.setEntity(reqEntity);
            // 设置超时时间
            httppost.setConfig(getConfig());
            response = httpClient.execute(httppost);
            resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static String httpFile(String url, Map<String, String> param, InputStream inputStream) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 处理https链接
        if (url.startsWith("https://")) {
            httpClient = sslClient();
        }
        String resultString = "";
        CloseableHttpResponse response = null;
        HttpPost httppost = new HttpPost(url);
        try {
            // HttpMultipartMode.RFC6532参数的设定是为避免文件名为中文时乱码
            MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
            // 设置请求的编码格式
            builder.setCharset(Consts.UTF_8);
            builder.setContentType(ContentType.MULTIPART_FORM_DATA);
            // 添加文件,也可以添加字节流
//			builder.addBinaryBody("file", file);
            //或者使用字节流也行,根据具体需要使用
            builder.addBinaryBody("file",inputStream);
            // 或者builder.addPart("file",new FileBody(file));
            // 添加参数
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addTextBody(key, param.get(key));
                }
            }
            //httppost.addHeader("token", param.get("token"));
            HttpEntity reqEntity = builder.build();
            httppost.setEntity(reqEntity);
            // 设置超时时间
            httppost.setConfig(getConfig());
            response = httpClient.execute(httppost);
            resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return resultString;
    }


    //辅助方法:这个用来设置超时的;
    private static RequestConfig getConfig() {
        return RequestConfig.custom().setConnectionRequestTimeout(60000).setSocketTimeout(120000)
                .setConnectTimeout(60000).build();
    }

    /**
     * 设置SSL请求处理
     */
    private static CloseableHttpClient sslClient() {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                @Override
                public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1) {
                    // TODO Auto-generated method stub
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    // TODO Auto-generated method stub
                    return null;
                }

            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLConnectionSocketFactory sslConnectionSocketFactory = SSLConnectionSocketFactory.getSocketFactory();
            return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }


}
